home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Extra 1997 #1
/
Amiga Plus Extra 1997 #1.iso
/
programme
/
tools
/
leoutils
/
leoclock.a
< prev
next >
Wrap
Text File
|
1996-03-26
|
8KB
|
319 lines
; . _ . . .
; | _ _ / \| _ _ | /| /| /|
; | |_)/ \( | / \| `|/ | | |
; |__|_,\_/ \_/|_\_/|_,|\ |o | |
;
; 1993-04-27
; 1993-06-28
; 1995-02-09
; 1996-03-26
;
;
; Here it is, the complete OS 2.0 clock that fits in one (1) FFS
; disk block; less than 512 bytes, that is.
;
; If you get this any smaller, or just want to write something
; to me, please mail me to the following addresses:
;
; Henrik Herranen
; Atomikatu 6 A 9
; SF-33720 Tampere
; Finland
;
; e-mail: leopold@cs.tut.fi
;
; New for v1.01: The clock now fits on 1 OFS disk block (488 bytes)!
; New for v1.10: With help from jhsa@cs.tut.fi and albert@cs.tut.fi 36
; bytes saved (JUST LOOK AT THE OPENING OF LIBRARIES!) :-) .
; New for v1.11: With help from Timo Kaikumaa (timok@cs.tut.fi) another
; 12 bytes went away. 440 to go.
; The following lines would normally be included from external files
; include 'ainclude:macros.i'
; include 'ainclude:include.i'
_LVOOpenLibrary EQU -552
_LVOChangeWindowBox EQU -486
_LVOCloseLibrary EQU -414
_LVOOldOpenLibrary EQU -408
_LVOReplyMsg EQU -378
_LVOGetMsg EQU -372
_LVOWindowToFront EQU -312
_LVOSetTaskPri EQU -300
_LVOFindTask EQU -294
_LVOSizeWindow EQU -288
_LVOSetWindowTitles EQU -276
_LVOOpenWindow EQU -204
_LVODelay EQU -198
_LVODateStamp EQU -192
_LVOMoveWindow EQU -168
_LVOCloseWindow EQU -72
_LVOTextLength EQU -54
WBENCHSCREEN EQU 1
wd_WScreen EQU $2E
wd_UserPort EQU $56
wd_LeftEdge EQU $4
wd_TopEdge EQU $6
sc_Width EQU $C
sc_BarHeight EQU $1E
sc_RastPort EQU $54
lib_Revision EQU $16
IDCMP_CLOSEWINDOW equ $200
WFLG_CLOSEGADGET equ $8
WFLG_DEPTHGADGET equ $4
WFLG_DRAGBAR equ $2
;
; Here begins my code
;
WIDEST equr d4
CURRWIDTH equr d2
WIN equr a3
INTUITIONBASE equr d5
EXECBASE equr d6
GRAPHICSBASE equr a4
ASC0 equr d3
LAST_MINUTE equr d7
; The registers A2 and A5 are left for free use
section text,CODE
main:
; OpenLib dos
moveq.l #60-60,WIDEST
; moveq.l #-1,LAST_MINUTE ; Not necessarily needed
move.l $4.w,EXECBASE ; My version of A68k doesn't like the
; .w extension. Take it away if it
; disturbs your compiler.
move.l EXECBASE,a6
sub.l a1,a1 ; MyTask = FindTask(0);
jsr _LVOFindTask(a6)
move.l d0,-(sp) ; Store MyTask to stack
move.l d0,a1 ; InheritedPri = SetTaskPri(MyTask, 4);
moveq.l #4,d0
jsr _LVOSetTaskPri(a6)
move.w d0,-(sp) ; Store InheritedPri to stack
lea IntuitionName(pc),a1 ; IntuitionBase = OldOpenLibrary("intuition.library");
lea _LVOOldOpenLibrary(a6),a5
jsr (a5)
move.l d0,INTUITIONBASE
lea IntuitionName+7(pc),a1 ; DosBase = OldOpenLibrary("dos.library");
addq.w #'os'-'on',(a1)
subq.b #'i'-'d',-(a1)
jsr (a5)
move.l d0,-(sp)
lea IntuitionName+9(pc),a1
lea Gfx+8(pc),WIN
move.l -(WIN),-(a1) ; GraphicsBase = OldOpenLibrary("graphics.library");
move.l -(WIN),-(a1)
jsr (a5)
move.l d0,GRAPHICSBASE
move.l INTUITIONBASE,a6 ; Win = OpenWindow(&NewWin);
lea NewWin(pc),a0
jsr _LVOOpenWindow(a6)
move.l d0,WIN ; if (!Win) exit(0);
tst.l d0
beq FailedOpeningWindow
MainLoop:
move.l (sp),a6 ; DateStamp(&MyDate); (DosBase is on top of the stack)
lea MyDate(pc),a2
move.l a2,d1
jsr _LVODateStamp(a6)
; lea MyDate_Minute(pc),a2 ; if (MyDate_Minute != LastMinute)
addq.l #MyDate_Minute-MyDate,a2
cmp.l (a2),LAST_MINUTE
beq.s MinuteNotChanged
move.l INTUITIONBASE,a6 ; WindowToFront(Win);
move.l WIN,a0
jsr _LVOWindowToFront(a6)
MinuteNotChanged:
moveq.l #'0',ASC0 ; Here ASC0 gets its nominal value '0'
move.l (a2)+,LAST_MINUTE ; LastMinute = MyDate_Minute;
move.l wd_WScreen(WIN),a5 ; a5 = Win -> WScreen
lea TimeStr(pc),a1 ; TimeStr[0] = MyDate_Minute / 600 + '0';
move.l LAST_MINUTE,d0
divu.w #600,d0
bne.s 1$
subq.l #1,a1
1$: bsr.s setnum
moveq.l #60,d1 ; TimeStr[1] = MyDate_Minute / 60 + '0';
bsr.s divud1d0_setnum
moveq.l #10,d1 ; TimeStr[3] = MyDate_Minute / 10 + '0';
bsr.s adda1_divud1d0_setnum
bsr.s setnum ; TimeStr[4] = MyDate_Minute + '0';
move.l (a2)+,d0 ; TimeStr[6] = MyDate_Tick / 50 / 10 + '0';
divu.w #50,d0
move.l d0,-(sp) ; Store whole 32-bit division result for later use
ext.l d0
bsr.s adda1_divud1d0_setnum
bsr.s setnum ; TimeStr[7] = MyDate_Tick / 50 + '0';
bra.s aftersetnum
; The structures have moved here for easier access. Parts of the NewWindow
; structure has been changed to contain code.
MyDate:
MyDate_Days:
Gfx: dc.b "grap"
MyDate_Minute:
dc.b "hics"
MyDate_Tick:
Pad: dc.b 0
IntuitionName:
dc.b "intu"
TimeStr:
dc.b "ition.library"
NewWin:
dc.w 0,0,60,20 ; Left, Top, Width, Height
dc.b 1,2 ; DetailPen, BlockPen
dc.l IDCMP_CLOSEWINDOW ; IDCMP flags
dc.l WFLG_CLOSEGADGET+WFLG_DEPTHGADGET+WFLG_DRAGBAR ; Flags
dc.l 0 ; *FirstGadget
dc.l 0 ; *CheckMark
dc.l 0 ; *WindowTitle
; Changing the length of this code will kill the compiler. The correct length
; is 16 bytes (move.b is 4 bytes, other commands 2 bytes/cmd)
adda1_divud1d0_setnum: ; *Screen, *BitMap, Min/Max-Width/Height
move.b #':',(a1)+
divud1d0_setnum:
divu.w d1,d0
setnum:
or.b ASC0,d0 ; This is "or" and not "add" because "or" might be faster :-)
move.b d0,(a1)+
swap d0 ; These were the most common commands after calling setnum!
ext.l d0 ; The code is not always needed, but doesn't do any harm either,
; and again another 8 bytes was saved!
rts
; End of code inserted to NewWindow structure
WantedLoc:
dc.w WBENCHSCREEN ; Type of mother screen
; End of NewWindow structure
aftersetnum:
clr.b (a1) ; NULL terminate string
move.l INTUITIONBASE,a6 ; SetWindowTitles(Win, &TimeStr[0 (or 1)], (UBYTE *) ~0L);
move.l WIN,a0
; Now a2 points to the next longword after MyDate_Tick
; Thus, by adding 1 you can get the address of TimeStr!
addq.l #TimeStr-MyDate_Tick-4,a2
exg a1,a2
move.l a1,ASC0 ; ASC0 looses its value '0' here!!!
sub.l a1,a2 ; a2 = length of string
; Display "LEN=",long,a2
; Display "PTR=",long,a1
move.l a2,-(sp) ; put length to stack
move.w #-1,a2 ; no ScreenTitle string
jsr _LVOSetWindowTitles(a6)
lea sc_RastPort(a5),a1 ; CurrWidth = TextLength(Win->WScreen.RastPort, TimeStr[0/1], 8/7);
move.l ASC0,a0 ; ASC0 isn't '0' anymore
move.l (sp)+,d0
move.l GRAPHICSBASE,a6
jsr _LVOTextLength(a6)
move.w d0,CURRWIDTH
cmp.w WIDEST,CURRWIDTH ; if (CurrWidth > Widest) {
ble.s EndUpdate
move.l INTUITIONBASE,a6 ; MoveWindow(Win, ##, 0);
move.l WIN,a0
moveq.l #-60-24,d0
add.w sc_Width(a5),d0 ; a5 still contains the Win->WScreen ptr
sub.w CURRWIDTH,d0
move.w d0,ASC0 ; ASC0 isn't '0'
lea WantedLoc(pc),a2
sub.w (a2),d0
move.w ASC0,(a2) ; ASC0 isn't '0'
moveq.l #0,d1
jsr _LVOMoveWindow(a6)
move.l WIN,a0 ; SizeWindow(Win, ##, ##);
move.w CURRWIDTH,d0
sub.w WIDEST,d0
moveq.l #1,d1
add.b sc_BarHeight(a5),d1 ; a5 still contains the Win->WScreen ptr
lea NewWin+6(pc),a5 ; Address of CurrWinHeight to a5
sub.w (a5),d1
add.w d1,(a5)
jsr _LVOSizeWindow(a6)
move.w CURRWIDTH,WIDEST
EndUpdate: ; } /* end if(CurrWidth > Widest) */
moveq.l #50,d1
sub.w (sp),d1 ; Get former tick / 50 division % from upper word of last stack item
addq.l #4,sp ; Clear last stack item (whole word!)
move.l (sp),a6 ; Now DosBase is on top of the stack
jsr _LVODelay(a6)
move.l EXECBASE,a6 ; if (!GetMsg(Win -> UserPort)) goto MainLoop
move.l wd_UserPort(WIN),a0
jsr _LVOGetMsg(a6)
tst.l d0
beq MainLoop
move.l d0,a1 ; ReplyMsg(WinIDCMP);
jsr _LVOReplyMsg(a6)
move.l INTUITIONBASE,a6 ; CloseWindow(Win);
move.l WIN,a0
jsr _LVOCloseWindow(a6)
FailedOpeningWindow:
move.l EXECBASE,a6
lea _LVOCloseLibrary(a6),a5 ; CloseLib(GraphicsBase);
move.l GRAPHICSBASE,a1
jsr (a5)
move.l (sp)+,a1 ; CloseLib(DosBase); (+ restore DosBase from stack)
jsr (a5)
move.l INTUITIONBASE,a1 ; CloseLib(IntuitionBase);
jsr (a5)
move.w (sp)+,d0 ; Restore InheritedPri from stack
move.l (sp)+,a1 ; Restore MyTask from stack
jsr _LVOSetTaskPri(a6) ; SetTaskPri(MyTask, InheritedPri);
moveq.l #0,d0
rts
END